using System;
using System.Data.SqlClient;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ApplicationLibrary;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.Preferences;
using ApplicationLibrary.SqlConnector;
using ApplicationManager.Library;
using System.Reflection;
using ApplicationLibrary.Libraries;

namespace ApplicationManager
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public partial class frmMain : System.Windows.Forms.Form
    {
        MoonLighting moonLight = null;
        public frmMain()
        {
            InitializeComponent();
            InitializeAuxComponent();
        }

        private void InitializeAuxComponent()
        {
            GlobalInfo.ToolStrip = new StripInfo(tssMessage, tssProgressBar);
            GlobalInfo.mainForm = this;
            GlobalInfo.CurrentDate = DateTime.Today;
            Application.Idle += new EventHandler(Application_Idle);

            System.Globalization.CultureInfo cInfo = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
            cInfo.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
            System.Threading.Thread.CurrentThread.CurrentCulture = cInfo;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
        private static extern short GetKeyState(int keyCode);

        private void Application_Idle(object sender, EventArgs e)
        {
            bool CapsLock = (((ushort)GetKeyState(0x14 /*VK_CAPITAL*/)) & 0xffff) != 0;
            bool NumLock = (((ushort)GetKeyState(0x90 /*VK_NUMLOCK*/)) & 0xffff) != 0;
            bool ScrollLock = (((ushort)GetKeyState(0x91 /*VK_NUMLOCK*/)) & 0xffff) != 0;
            tssCapsLock.Text = CapsLock ? "CAP" : "";
            tssNumLock.Text = NumLock ? "NUM" : "";
            tssScrollLock.Text = ScrollLock ? "SCR" : "";
            tssDate.Text = GlobalInfo.CurrentDate.ToShortDateString();
            tssUser.Text = GlobalInfo.UserInfo.User;
        }

        protected override void OnLoad(EventArgs e)
        {
            tssProgressBar.Visible = true;
            tssProgressBar.Style = ProgressBarStyle.Marquee;

            // Mi connetto al Database
            GlobalInfo.DBaseInfo.dbManager = new SqlManager();
            if (!GlobalInfo.DBaseInfo.dbManager.CreateConnection())
            {
                this.Close();
                return;
            }

            PreferencesManager<GlobalPref> globalPref = new PreferencesManager<GlobalPref>("", null);
            GlobalPref pref = globalPref.ReadPreference();
            if (pref.ForceLanguage)
            {
                string lang = Enum.GetName(typeof(Languages), pref.Language).Replace('_', '-');
                System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang, false);
            }

            // Faccio la login
            // Controllo se devo saltarla
            loginForm login = new loginForm();
            if (!GlobalInfo.LoginInfo.RememberLastLogin || !login.CheckUser(GlobalInfo.LoginInfo.LastUser, GlobalInfo.LoginInfo.LastPassword))
            {
                if (login.ShowDialog() != DialogResult.OK)
                {
                    this.Close();
                    return;
                }
            }
            login.Dispose();
            login = null;

            pref = globalPref.ReadPreference();
            GlobalInfo.globalPref = pref;
            if (pref.ForceLanguage)
            {
                string lang = Enum.GetName(typeof(Languages), pref.Language).Replace('_', '-');
                System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang, false);
            }

            base.OnLoad(e);
        }

        protected override void OnShown(EventArgs e)
        {
            // Controllo che il programma sia correttamente registrato
            if (!SerialManager.Load())
            {
                registerForm rF = new registerForm(ModuleManager.ApplicationName);
                if (rF.ShowDialog() == DialogResult.Cancel)
                    Application.Exit();
            }

            // Carica i moduli
            if (!ModuleManager.LoadModules())
                Application.Exit();

            //if (!SerialManager.ActivateApplication(SerialManager.SerialNo))
            //{
            //    MessageBox.Show(this,Properties.Resources.Msg_WrongCode,
            //                    Properties.Resources.Msg_Attention,
            //        MessageBoxButtons.OK, MessageBoxIcon.Error);
            //    Application.Exit();
            //}

            this.Text = ModuleManager.ApplicationName;
            ShowSplash();

            GlobalInfo.ToolStrip.Text = "";

            // Aggancio il menu
            WeifenLuo.WinFormsUI.Docking.DockContent menu = new applicationmenuForm(this);

            //menu.MdiParent = this;
            menu.Show(dockPanel1);

            if (GlobalInfo.UserInfo.userType != UserType.Administrator)
            {
                tsmUsers.Visible = false;
            }

            tssProgressBar.Visible = false;
            tssProgressBar.Style = ProgressBarStyle.Blocks;

            // AutoUpdater
#if (DEBUG)
            Version vrs = Assembly.GetEntryAssembly().GetName().Version;
            moonLight = new MoonLighting();
            moonLight.Method = CheckNewVersion.CheckVersion;
            CheckNewVersion.OpenForm += new EventHandler(CheckNewVersion_OpenForm);
            CheckNewVersion.GiveMessage += new EventHandler(CheckNewVersion_GiveMessage);
            moonLight.Execute(new CheckNewVersion.parameters() { ApplicationName = ModuleManager.ApplicationName, Version = vrs, Verbose = false });
#endif
            base.OnShown(e);
        }

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            for (int t = tsmWindows.DropDownItems.Count - 1; t >= 0; t--)
            {
                FormToolStripMenuItem menuItem = (FormToolStripMenuItem)tsmWindows.DropDownItems[t];
                if (menuItem.Form.GetType().BaseType == typeof(ApplicationLibrary.DBManager.DocumentForm) ||
                    menuItem.Form.GetType().BaseType.BaseType == typeof(ApplicationLibrary.DBManager.DocumentForm))
                {
                    menuItem.Form.Close();
                    if (Application.OpenForms[menuItem.Form.Name] != null)
                        e.Cancel = true;
                }
            }

            base.OnClosing(e);
        }

        public void AddFormToMenu(Form myform)
        {
            FormToolStripMenuItem menuItem = new FormToolStripMenuItem();
            menuItem.Form = myform;
            menuItem.Text = myform.Text;
            menuItem.Image = myform.Icon.ToBitmap();
            menuItem.Click += new EventHandler(menuItem_Click);

            tsmWindows.DropDownItems.Add(menuItem);

#if !DEBUG
			tsmUnlockRecord.Enabled = tsmWindows.DropDownItems.Count < 2;
#endif
        }

        public void RemoveFormFromMenu(Form myform)
        {
            for (int i = 0; i < tsmWindows.DropDownItems.Count; i++)
                if (((FormToolStripMenuItem)tsmWindows.DropDownItems[i]).Form == myform)
                    tsmWindows.DropDownItems.RemoveAt(i);

            tsmUnlockRecord.Enabled = tsmSystem.DropDownItems.Count < 2;
        }

        private void menuItem_Click(object sender, EventArgs e)
        {
            ((FormToolStripMenuItem)sender).Form.Activate();
        }

        private void mnuUnlock_Click(object sender, EventArgs e)
        {
            // DELETE FROM Lock WHERE User=@p1;
            string sDelete = string.Format
                (
                    "DELETE FROM {0} where {1}=@p1",
                    AM_Locks.Name,
                    AM_Locks.Username
                );
            SqlABParameter p1 = new SqlABParameter("@p1", AM_Locks.Username);

            QueryBuilder qb = new QueryBuilder();
            qb.AddManualQuery("DELETE FROM {0}", AM_Locks.Name);
            qb.AddCompare(AM_Locks.Username, p1);

            try
            {
                SqlABCommand sc = new SqlABCommand(qb.Query, GlobalInfo.DBaseInfo.dbManager.DB_Connection);

                sc.Parameters.Add(p1);

                p1.Value = GlobalInfo.UserInfo.User;
                sc.ExecuteScalar();
            }
            catch (SqlException sExc)
            {
                MessageBox.Show(sExc.Message, "Unlock");
            }
        }

        #region Open & Close Form
        public Form ApriForm(Form form, bool modal)
        {
            try
            {
                if (modal)
                {
                    if (form.GetType().BaseType.Equals(typeof(WeifenLuo.WinFormsUI.Docking.DockContent)))
                        ((WeifenLuo.WinFormsUI.Docking.DockContent)form).ShowDialog(dockPanel1);
                    else
                        form.ShowDialog(dockPanel1);
                }
                else
                {
                    //form.MdiParent = this;
                    form.Closed += new EventHandler(ChiudiForm);
                    if (form.GetType().Equals(typeof(WeifenLuo.WinFormsUI.Docking.DockContent)))
                        form.Show(dockPanel1);
                    else
                        ((WeifenLuo.WinFormsUI.Docking.DockContent)form).Show(dockPanel1);

                    AddFormToMenu(form);
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.StackTrace, exc.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return form;
        }

        private void ChiudiForm(object sender, System.EventArgs e)
        {
            RemoveFormFromMenu((Form)sender);
        }

        #endregion

        private void tsmUsers_Click(object sender, EventArgs e)
        {
            ApriForm(new usersForm(), false);
        }

        private void tssChangeDate_Click(object sender, EventArgs e)
        {
            ApriForm(new dateForm(), true);
        }

        private void ShowSplash()
        {
            splashForm splash = new splashForm();
            splash.Owner = this;
            splash.StartPosition = FormStartPosition.CenterParent;
            splash.ShowDialog();
        }

        private void tsmInfo_Click(object sender, EventArgs e)
        {
            AboutForm about = new AboutForm();
            about.ShowDialog();
        }

        private void tsmCounter_Click(object sender, EventArgs e)
        {
            ApriForm(new ApplicationLibrary.CounterManager.counterForm(), false);
        }

        private void tsmCodes_Click(object sender, EventArgs e)
        {
            ApriForm(new ApplicationLibrary.CounterManager.codesForm(), false);
        }

        private void tsmPreferences_Click(object sender, EventArgs e)
        {
            PreferenceForm pf = new PreferenceForm();
            pf.AddPanel(new GlobalPreferencePanel(""));
            pf.AddPanel(new MailPreferencePanel(""));
            pf.AddPanel(new NHUnspellPreferencePanel(""));
            pf.AddPanel(new PrinterPreferencePanel(""));

            foreach (ApplicationMenuModule amm in ModuleManager.ModuleList)
            {
                pf.AddPanel(GetPreferencePanel(amm));
            }
            ApriForm(pf, true);
        }

        private PreferencePanel[] GetPreferencePanel(ApplicationMenuModule amm)
        {
            string module = amm.Namespace.Module;
            amm.Namespace.Application = "ModuleData.RegisterModule";
            RegisterModule registerTable = (RegisterModule)DllManager.CreateIstance(amm.Namespace, null);
            if (registerTable != null)
            {
                return registerTable.RegisterPreferences();
            }

            return null;
        }

        private void tsmRegistration_Click(object sender, EventArgs e)
        {
            registerForm rF = new registerForm(ModuleManager.ApplicationName);
            rF.LoadFromBinary = true;
            rF.ShowDialog();
        }

        private void tsmDontRememb_Click(object sender, EventArgs e)
        {
            GlobalInfo.LoginInfo.RememberLastLogin = false;
            GlobalInfo.DBaseInfo.dbManager.WriteConfigFile();
            MessageBox.Show(Properties.Resources.Msg_UserNotRemember,
                                Properties.Resources.Msg_Attention,
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void tsmNewVersion_Click(object sender, EventArgs e)
        {
            Version vrs = Assembly.GetEntryAssembly().GetName().Version;
            moonLight = new MoonLighting();
            NotifyForm nf = new NotifyForm();
            moonLight.Method = CheckNewVersion.CheckVersion;
            CheckNewVersion.GiveMessage += new EventHandler(CheckNewVersion_GiveMessage);
            moonLight.Execute(new CheckNewVersion.parameters { ApplicationName = ModuleManager.ApplicationName, Version = vrs, Verbose = true });
        }

        void CheckNewVersion_OpenForm(object sender, EventArgs e)
        {
            NotifyForm nf = new NotifyForm();
            nf.ShowDialog();
            moonLight.CancelAsync();
            Application.DoEvents();
        }

        void CheckNewVersion_GiveMessage(object sender, EventArgs e)
        {
            moonLight.CancelAsync();
        }
    }
}